/**
 *
 */
package ue.a4;

import gdp.stdlib.StdDraw;

import java.awt.Color;

/**
 * @author mordan
 * @version 823.23 Rev 23a (Beta) Fork 1
 *
 */
public class Tree {

	static boolean Debug = false;

	/**
	 *
	 * @param string
	 *            title
	 * @param double x,y n
	 * @param string
	 *            finish
	 * @return void
	 *
	 *         formated output if Debug==TRUE
	 */
	public static void outp(String title, double x, double y, String finish) {
		System.out.print(title + ": ");
		System.out.printf("(%1.3f,%1.3f)", x, y);
		System.out.print(finish);
	}

	/**
	 *
	 * @param string
	 *            title
	 * @param double n
	 * @param string
	 *            finish
	 * @return void
	 *
	 *         formated output if Debug==TRUE
	 */
	public static void outz(String title, double n, String finish) {
		System.out.print(title + ": ");
		System.out.printf("(%1.3f)", n);
		System.out.print(finish);
	}

	/**
	 *
	 * @param string
	 *            title
	 * @param int n
	 * @param string
	 *            finish
	 * @return void
	 *
	 *         formated output if Debug==TRUE
	 */
	public static void outz(String title, int n, String finish) {
		System.out.print(title + ": " + n + finish);
	}

	/**
	 *
	 * @param double low lowest value
	 * @param double high highest value
	 * @return double random value
	 */

	public static double r(double low, double high) {
		return (Math.random() * (high - low)) + low;
	}

	/**
	 *
	 * @param int iteration
	 * @param double x0 Point 1 counterclockwise
	 * @param double y0
	 * @param double x1 Point 2
	 * @param double y1
	 * @return void
	 *
	 *         calculates and draws square
	 *
	 *         stops recursion if iteration reached 0. otherwise calls
	 *         drawtriangle
	 */

	public static void drawsquare(int iteration, double x0, double y0, double x1, double y1) {
		double x2, y2, x3, y3 = 0;
		double dx = (x1 - x0);
		double dy = (y0 - y1);
		if (Debug) {
			outz("4-it", iteration, " ");
			outp("d", dx, dy, " ");
		}
		// calc square
		x2 = x1 + dy;
		y2 = y1 + dx;
		x3 = x0 + dy;
		y3 = y0 + dx;

		if (Debug) {
			outp("p0", x0, y0, " ");
			outp("p1", x1, y1, " ");
			outp("p2", x2, y2, " ");
			outp("p3", x3, y3, "\n");
			// outp("p4", x4, y4, "\n");
		}

		// draw square
		rcolor(iteration);
		StdDraw.line(x0, y0, x1, y1);
		StdDraw.line(x1, y1, x2, y2);
		StdDraw.line(x2, y2, x3, y3);
		StdDraw.line(x3, y3, x0, y0);

		if (iteration == 0) {
			return;
		} else {
			drawtriangle(iteration - 1, x3, y3, x2, y2);
		}
	}

	/**
	 *
	 * @param int iteration
	 * @return void
	 *
	 *         changes pen color based on random
	 */
	public static void rcolor(int iteration) {
		int r, g, b = 0;
		r = (int) r(20, 230);
		g = (int) r(20, 230);
		b = (int) r(20, 230);
		StdDraw.setPenColor(new Color(r, g, b));
	}

	/**
	 *
	 * @param int iteration
	 * @param double x0 Point 1 counterclockwise
	 * @param double y0
	 * @param double x1 Point 2
	 * @param double y1
	 * @return void
	 *
	 *         calculates and draws triange calls drawsquare for each leg
	 */
	public static void drawtriangle(int iteration, double x0, double y0, double x1, double y1) {

		double x4, y4 = 0;
		double dx = (x1 - x0);
		double dy = (y0 - y1);
		if (Debug) {
			outz("3-it", iteration, " ");
			outp("d", dx, dy, " ");
		}

		// triangle
		double d = r(0.1, 0.9);

		// new point
		//

		x4 = ((d * x0) + ((1 - d) * x1)) + ((Math.sqrt(d * (1 - d))) * dy);
		y4 = ((d * y0) + ((1 - d) * y1)) + ((Math.sqrt(d * (1 - d))) * dx);
		if (Debug) {
			outp("p0", x0, y0, " ");
			outp("p1", x1, y1, " ");
			// outp("p2", x2, y2, " ");
			// outp("p3", x3, y3, " ");
			outp("p4", x4, y4, "\n");
		}

		// draw triangle

		rcolor(iteration);
		StdDraw.line(x0, y0, x4, y4);

		rcolor(iteration);
		StdDraw.line(x4, y4, x1, y1);

		drawsquare(iteration, x0, y0, x4, y4);
		drawsquare(iteration, x4, y4, x1, y1);

	}

	/**
	 *
	 * @param string
	 *            args Input
	 * @return void
	 *
	 *         defines canvas relative to iteration calls draw
	 */
	public static void main(String[] args) {
		int N = Integer.parseInt(args[0]);

		double myscale = 15 - ((15 - 4) * Math.exp(-N));

		StdDraw.setXscale(0, myscale);
		StdDraw.setYscale(0, myscale);
		drawsquare(N, (myscale / 2) - 1, 0, (myscale / 2) + 1, 0);
		StdDraw.show(800);

	}
}
